<?php
function fps_define($name, $default) {
	if (!defined($name)) {
		define($name, $default);
	}
}

fps_define('APP_ROOT', dirname(__DIR__));

fps_define('FPS_ENV',            'FPS_ENV');
fps_define('FPS_URI',            'FPS_URI');
fps_define('FPS_ACTION',         'FPS_ACTION');
fps_define('FPS_MODULE',         'FPS_MODULE');
fps_define('FPS_PUBLIC_MODULES', '/index:/login');
fps_define('FPS_PROJECT',        'module');
fps_define('FPS_MODULE_ROOT',    APP_ROOT.'/'.FPS_PROJECT);
fps_define('FPS_WITH_SESSION',   true);
fps_define('FPS_WITH_USER',      true);
fps_define('FPS_USER_TABLE',     'user');
fps_define('FPS_POST_FIELD',     'data');

include_once('db.php');
include_once('user.php');

function val(&$arr, $name, $def = null) {
	return isset($arr[$name]) ? $arr[$name] : $def;
}

function fps_config($name, $def = null) {
	return isset($GLOBALS['FPS_CONFIG'][$name]) ? $GLOBALS['FPS_CONFIG'][$name] : $def;
}

function fps_init_post() {
	// check post json data
	$cType = isset($_SERVER['HTTP_CONTENT_TYPE']) ? $_SERVER['HTTP_CONTENT_TYPE'] : '';
	if ($_SERVER['REQUEST_METHOD'] == 'POST' &&
		stripos($cType, 'application/json') !== false)
	{
		$json = file_get_contents("php://input");
		$post = json_decode($json, true);

		if (FPS_POST_FIELD) {
			if (isset($post[FPS_POST_FIELD])) {
				$_POST = $post[FPS_POST_FIELD];
			}
		}
		else if ($post) {
			$_POST = $post;
		}
	}
	else {
		$post = $_POST;
	}

	$_SERVER[FPS_ENV] = isset($post['env']) ? $post['env'] : array();
	$_SERVER[FPS_URI] = isset($post['uri']) ? $post['uri'] : 
		(isset($_GET['uri']) ? $_GET['uri'] : '/');
}

function fps_array_get(&$arr, $field_str) {
	$fs  = explode(',', $field_str);
	$res = [];

	foreach ($fs as $field) {
		if (isset($arr[$field])) {
			$res[$field] = $arr[$field];
		}
	}

	return $res;
}

function fps_get($name=null, $default = null, $format = null) {
	if (is_null($name)){ return $_GET; }
	return isset($_GET[$name]) ? ($format ? $format($_GET[$name]) : $_GET[$name]) : $default;
}

function fps_post($name=null, $default = null, $format = null) {
	if (is_null($name)){ return $_POST; }
	return isset($_POST[$name]) ? ($format ? $format($_POST[$name]) : $_POST[$name]) : $default;
}

function fps_cookie($name=null, $default = null, $format = null) {
	if (is_null($name)){ return $_COOKIE; }
	return isset($_COOKIE[$name]) ? ($format ? $format($_COOKIE[$name]) : $_COOKIE[$name]) : $default;
}

function fps_file($name=null, $default = null) {
	if (is_null($name)){ return $_FILES; }
	return isset($_FILES[$name]) ? $_FILES[$name] : $default;
}

function fps_session($name=null, $default = null) {
	if (is_null($name)){ return $_SESSION; }
	return isset($_SESSION[$name]) ? $_SESSION[$name] : $default;
}

// main framework start function
function fps_run() {
	fps_init_post();
	fpsUser::init();

	$uri = '/' . str_replace(array("\\", '-'), '/', $_SERVER[FPS_URI]);
	$uri = preg_replace('/[\/]{2,}/', '/', str_replace('.', '', $uri));
	$arr = explode('/', $uri);
	$action = (count($arr) > 2) ? array_pop($arr) : 'main';
	$uri = implode('/', $arr);
	$module = ($uri == '/') ? '/index' : $uri;

	$_SERVER[FPS_MODULE] = $module;
	$_SERVER[FPS_ACTION] = $action;

	$file = FPS_MODULE_ROOT . $module . '.php';
	$fn = 'action'. ucfirst($action);
	if ($uri == '/') {
		$cls = 'moduleIndex';
	}
	else {
		$cls = 'module';
		foreach ($arr as $name) {
			$cls .= ucfirst($name);
		}
	}

	if (file_exists($file)) {
		require_once($file);

		if (method_exists($cls, $fn)) {
			if (defined('FPS_SESSION_NAME')) {
				session_name(FPS_SESSION_NAME);
			}

			if (FPS_WITH_SESSION) {
				session_start();

				if (FPS_WITH_USER && !in_array($module, explode(':', FPS_PUBLIC_MODULES))) {
					// check login
					$user = fpsUser::get();

					if ($user['_id'] <= 0) {
						if (function_exists('fps_on_login')) {
							fps_on_login();
						}
						else {
							json_out(401, 'User Not Login');
						}
						exit;
					}
				}
			}

			if (method_exists($cls, 'beforeAction')) {
				call_user_func(array($cls, 'beforeAction'));
			}
			return call_user_func(array($cls, $fn));
		}
	}

	return false;
}